package com.bs.blogspace.aop;


import com.alibaba.fastjson.JSONObject;
import com.bs.blogspace.mapper.OperateLogMapper;
import com.bs.blogspace.pojo.OperateLog;
import com.bs.blogspace.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect//是一个切面类
@Component//交给IOC容器管理
public class LogAspect {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.bs.blogspace.anno.Log)")
    public Object recordeLog(ProceedingJoinPoint joinPoint) throws Throwable {
        //操作人ID-当前登录员工ID
        //获取请求头中的JWT令牌，解析令牌
        String jwt = request.getHeader("Authorization");
        Claims claims = JwtUtils.parseJWT(jwt);
        Integer oprateUser = (Integer) claims.get("id");
        System.out.println("获取JWT的ID：：：：：："+oprateUser);

        //操作时间
        LocalDateTime now = LocalDateTime.now();

        //操作类名
        String className = joinPoint.getTarget().getClass().getName();

        //操作方法
        String methName = joinPoint.getSignature().getName();
        
        //操作方法参数
        Object[] args = joinPoint.getArgs();
        String methParams = Arrays.toString(args);

        //调用原始目标方法运行
        long begin = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();

        //方法返回值
        String returnValue  = JSONObject.toJSONString(result);

        //操作时间
        Long cost = end-begin;

        //记录操作日志
        OperateLog operateLog = new OperateLog(null,oprateUser,now,
                className,methName,methParams,returnValue,cost);
        operateLogMapper.insert(operateLog);
        log.info("AOP,记录操作日志，{}",operateLog);
        return result;

    }

}
